﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web.UI;
using Library.WebControls.SimplePanelCallback;
using Library.WebControls.SimpleSplitContainer;
using Library.WebControls.SimpleTreeView;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.IO;

namespace Library.WebControls.SimpleFileExplorer {
	[Designer(typeof(SpFileExplorerDesigner))]
	[SupportsEventValidation]
	[DefaultProperty("FileStructTemplate")]
	[ToolboxData("<{0}:SpFileExplorer runat=server></{0}:SpFileExplorer>")]

	[DesignTimeVisible(true)]
	public class SpFileExplorer : BaseAjaxControl {
		protected override string StyleSheetFileName {
			get { return "spfileexplorer-ui.css"; }
		}

		public string RootPath { get; set; }

		private SimpleSplitContainer.SpSplitContainer _spliter;
		private SimpleTreeView.SpTreeView _tvFolder;
		private SpPanelCallback _divRight;
		//	private HtmlGenericControl _divPath;
		//	private HtmlGenericControl _divTool;

		protected override void CreateChildControls() {
			_spliter = new SpSplitContainer();
			_spliter.Width = new Unit("100%");
			_spliter.Direction = RepeatDirection.Horizontal;
			var leftPanel = new SpSpliterPanel();
			leftPanel.Vertical = VerticalAlign.Top;
			_spliter.Panels.Add(leftPanel);
			
			_tvFolder = new SpTreeView();
			_tvFolder.Width = new Unit("100%");
			_tvFolder.NodeExpended += new EventHandler<SpTreeNodeExpendedEventArgs>(TvFolderNodeExpended);
			_tvFolder.ItemBound += new SimpleItemBoundEventHandler<SpTreeNodeItemTemplate>(TvFolderItemBound);
			_tvFolder.DisplayEffect = Effect.Child;
			leftPanel.Controls.Add(_tvFolder);

			_divRight = new SpPanelCallback();
			var rightPanel = new SpSpliterPanel();
			rightPanel.Vertical = VerticalAlign.Top;
			_spliter.Panels.Add(rightPanel);
			//_divPath = new HtmlGenericControl("div");

			rightPanel.Controls.Add(_divRight);
			//	_divRight.Controls.Add(_divPath);
			//_divTool = new HtmlGenericControl("div");

			//_divRight.Controls.Add(_tableContent);
			Controls.Add(_spliter);

			_divRight.CustomCallback += (DivRightCustomCallback);
			LeftFolderWidth = new Unit("300px");
		}

		void DivRightCustomCallback(object sender, CustomCallbackEventArgs e) {
			var key = _divRight.GetClientQueryValue("__SPFEVTF_");
			var ev = new FileStructClickEventArgs();
			ev.ExpendedKey = key;
			ev.Level = 0;
			OnFileStructClick(ev);
		}

		[PersistenceMode(PersistenceMode.Attribute)]
		public Unit LeftFolderWidth {
			get {
				EnsureChildControls();
				return _spliter.Panels[0].Width;
			}
			set {
				EnsureChildControls();
				_spliter.Panels[0].Width = value;
			}
		}
		public override bool IsCallback {
			get {
				EnsureChildControls();
				return _tvFolder.IsCallback || _divRight.IsCallback;
			}
		}
		public override string ClientName {
			get {
				return base.ClientName;
			}
			set {
				EnsureChildControls();
				base.ClientName = value;
				_tvFolder.ClientName = value + "L";
				_divRight.ClientName = value + "R";
			}
		}
		protected override void OnLoad(EventArgs e) {
			base.OnLoad(e);
			IncludeScriptOnLoad(typeof(SpFileExplorer), "Ex", "Library.WebControls.SimpleFileExplorer.include.SpFileExplorer.js", UtilLib);
		}


		public string ImageFolder { get; set; }
		public override void DataBind() {
			EnsureChildControls();
			CreateFolderSource();
			base.DataBind();
		}

		public override string ID {
			get {
				return base.ID;
			}
			set {
				base.ID = value;
				EnsureChildControls();
				_spliter.ID = value;
				_tvFolder.ID = value + "L";
				_divRight.ID = value + "R";
			}
		}

		protected virtual void CreateFolderSource() {
			var handled = false;
			var e = new ExplorerFolderCreatingEventArgs();
			var handler = ExplorerFolderCreating;
			if (handler != null) {
				handler(this, e);
				handled = true;
			}
			FileStructDatasource foders;
			if (handled) {
				foders = e.Datasource;
			} else {
				foders = GetFileStruct(RootPath, true, false);
			}

			_tvFolder.DataSource = foders;
			_tvFolder.TextField = "Name";
			_tvFolder.KeyField = "Key";
			//_tvFolder.DataBind();
		}

		protected virtual FileStructDatasource GetFileStruct(string realPath, bool includeFolder, bool includeFile) {
			var foders = new FileStructDatasource();
			if (Directory.Exists(realPath)) {
				var parentlength = RootPath.Length;
				var last = RootPath[RootPath.Length - 1];
				if (last != Path.VolumeSeparatorChar && last != Path.AltDirectorySeparatorChar) {
					parentlength++;
				}
				if (includeFolder) {
					var dirs = Directory.GetDirectories(realPath);
					foreach (var dir in dirs) {
						var localPath = dir.Substring(parentlength);

						var fileStruct = new SpFileStruct();
						fileStruct.FileType = SpFileType.Folder;
						fileStruct.Name = Path.GetFileNameWithoutExtension(localPath);
						fileStruct.ParentFolder = Path.GetDirectoryName(localPath);
						fileStruct.Size = 0;
						fileStruct.State = DataItemState.OnClientRequest;
						foders.Add(fileStruct);
					}
				}

				if (includeFile) {
					
					var files = Directory.GetFiles(realPath);
					foreach (var file in files) {
						var localPath = file.Substring(parentlength);
						var fileInfo = new FileInfo(file);

						var fileStruct = new SpFileStruct();
						fileStruct.FileType = SpFileType.File;
						fileStruct.Name = Path.GetFileName(file);
						fileStruct.ParentFolder = Path.GetDirectoryName(localPath);
						fileStruct.Size = fileInfo.Length;
						fileStruct.State = DataItemState.OnClientRequest;
						foders.Add(fileStruct);
					}
				}
			}
			return foders;
		}


		void TvFolderItemBound(object sender, SimpleItemBoundEventArgs<SpTreeNodeItemTemplate> e) {
			//var fileStruct = e.Item.DataItem as SpFileStruct;
			//if (fileStruct != null) {
			//  var div = new HtmlGenericControl("span");
			//  var divImage = new HtmlGenericControl("div");
			//  var img = new Image { ImageUrl = ImageFolder };
			//  divImage.Controls.Add(img);

			//  var divText = new HtmlGenericControl("div") { InnerText = fileStruct.Name };
			//  div.Controls.Add(divImage);
			//  div.Controls.Add(divText);
			//}
			var img = new Image();
			img.ImageUrl = "~/style/simple/images/folder.png";
			var lit = new HtmlGenericControl("div");
			lit.Attributes["onclick"] = String.Format("{0}.ShowContent(this)", ClientName);
			lit.InnerText = e.Item.InnerText;
			e.Item.InnerText = String.Empty;
			e.Item.Controls.Add(img);
			e.Item.Controls.Add(lit);
		}

		void TvFolderNodeExpended(object sender, SpTreeNodeExpendedEventArgs e) {
			OnFolderExpended(new FolderExpendedEventArgs(e.ExpendedKey, e.Parameter, e.ExpendedLevel));

		}
		protected virtual void OnFolderExpended(FolderExpendedEventArgs e) {
			var handled = false;
			var handler = FolderExpended;
			if (handler != null) {
				handler(this, e);
				handled = true;
			}
			if (!handled) {
				e.Datasource = GetFileStruct(Path.Combine(RootPath, e.ExpendedKey), true, false);
			}
			_tvFolder.DataSource = e.Datasource;
			_tvFolder.DataBind();
		}

		protected virtual void OnFileStructClick(FileStructClickEventArgs e) {
			var handler = FileStructClick;
			var handled = false;
			if (handler != null) {
				handled = true;
				handler(this, e);
			}
			if (!handled) {
				e.Datasource = GetFileStruct(Path.Combine(RootPath, e.ExpendedKey), false, true);
			}

			if (e.Datasource != null) {
				EnsureChildControls();
				int index = -1;
				foreach (var file in e.Datasource) {
					index++;
					var item = new FileStructItemTemplate();
					_divRight.Content.Controls.Add(item);
					item.DataItem = file;
					item.DisplayIndex = index;
					item.DataItemIndex = index;
					if (FileStructTemplate != null) {
						FileStructTemplate.InstantiateIn(item);
					} else {

						var div = item;//new HtmlGenericControl("div");

						var divImg = new HtmlGenericControl("div");
						div.Controls.Add(divImg);
						var img = new Image();
						if (file.FileType == SpFileType.Folder)
							img.ImageUrl = "~/style/simple/images/folder32.png";
						else if (file.FileType == SpFileType.File)
							img.ImageUrl = "~/style/simple/images/file32.png";
						divImg.Controls.Add(img);
						var divText = new HtmlGenericControl("div");
						div.Controls.Add(divText);
						divText.InnerText = file.Name;
					}

					var itemBoundHanlder = FileStructItemBound;
					if (itemBoundHanlder != null) {
						itemBoundHanlder(this, new SimpleItemBoundEventArgs<FileStructItemTemplate>(item));
					}
				}
				base.DataBind();
			}
		}

		[Description("")]
		[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
		[MergableProperty(false)]
		[Category("Data")]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
		[DefaultValue("")]
		[TemplateContainer(typeof(FileStructItemTemplate))]

		public ITemplate FileStructTemplate { get; set; }



		public event EventHandler<ExplorerFolderCreatingEventArgs> ExplorerFolderCreating;
		public event EventHandler<FolderExpendedEventArgs> FolderExpended;
		public event EventHandler<FileStructClickEventArgs> FileStructClick;
		public event SimpleItemBoundEventHandler<FileStructItemTemplate> FileStructItemBound;

		protected override void CreateClientObjectAtRender(HtmlTextWriter writer) {
			BeginScriptTag(writer);
			writer.Write("{0}=new SpFileExplorer('{0}', {1}, {2});", ClientName, _tvFolder.ClientName, _divRight.ClientName);
			EndScriptTag(writer);
		}

		protected override void Render(HtmlTextWriter writer) {
			if (!Visible) return;
			if (_tvFolder.IsCallback) {
				_tvFolder.RenderControl(writer);
			} else if (_divRight.IsCallback) {
				_divRight.RenderControl(writer);
			} else {
				base.Render(writer);
			}
		}
	}
}
